﻿using System.Diagnostics;
using System.Drawing;

namespace System
{
  [DebuggerStepThrough]
  public static class ColorExtensions
  {
    public static Color GetForegroundColor(this Color input)
    {
      if (Math.Sqrt(input.R*input.R*.241 + input.G*input.G*.691 + input.B*input.B*.068) > 128)
        return Color.Black;
        
      return Color.White;
    }

    public static Color ToGray(this Color input)
    {
      int g = (int) (input.R*.299) + (int) (input.G*.587) + (int) (input.B*.114);
      return Color.FromArgb(input.A, g, g, g);
    }

    /// <summary>
    /// This method applies lighting to a color.
    /// For instance, a color that has a lighting factor of 1 applies, appears at its original value.
    /// A color with a lighting factor of 0.5 appears only half as bright as it was before.
    /// A color with a lighting factor of 1.5 appears roughly twice as bright as before.
    /// A color with a lightning factor of 2 appears white.
    /// </summary>
    /// <param name="originalColor">Base color</param>
    /// <param name="lightFactor">Amount of light applied to the color</param>
    public static Color GetLitColor(this Color originalColor, float lightFactor)
    {
      // Depending on the transformation required, we will proceed differently
      if (lightFactor - 1.0f < 0.01f && lightFactor - 1.0f > -0.01f)
        // No transformation needed
        return originalColor;
      if (lightFactor >= 2.0f)
        // No calculations needed. This is white
        return Color.White;

      // OK, lighting is required, so here we go
      int red = originalColor.R;
      int green = originalColor.G;
      int blue = originalColor.B;

      // Do we need to add or remove light?
      if (lightFactor < 1.0f)
      {
        // Darken
        // We can simply reduce the color intensity
        var newColor = Color.FromArgb((int)(red * lightFactor), (int)(green * lightFactor), (int)(blue * lightFactor));
        return newColor;
      }
      else
      {
        // Lighten
        // We do this by approaching 256 for a light factor of 2.0f
        float lightFactor2 = lightFactor;
        if (lightFactor2 > 1.0f) lightFactor2 -= 1.0f;
        int iRed2 = 255 - red;
        int iGreen2 = 255 - green;
        int iBlue2 = 255 - blue;
        red += (int)(iRed2 * lightFactor2);
        green += (int)(iGreen2 * lightFactor2);
        blue += (int)(iBlue2 * lightFactor2);
        if (red > 255) { red = 255; }
        if (green > 255) { green = 255; }
        if (blue > 255) { blue = 255; }
        var newColor = Color.FromArgb(red, green, blue);
        return newColor;
      }
    }

  }
}